class Hook {
      constructor()
      {
           this.queue = new Array();
      }
      static instance()
      {
          if(!Hook._instance)
          {
                Hook._instance = new Hook();
          }
          return Hook._instance;
      }


      addAction(hook, func)
      {
          this.queue[hook] = this.queue[hook] || new Array();
          if (typeof func == 'function') {
              this.queue[hook].push(func);
          } else if (typeof func == 'string') {
              this.queue[hook].push(this.window[func]);
          }
      }
      doAction(hook)
      {
          var parameters = Array.prototype.slice.call(arguments, 1);
          var functions = this.queue[hook];
          for (var i = 0; i < functions.length; i++) {
          //  functions[i]();
            //console.log(222)
              this.call_user_func_array(functions[i], parameters);
          }
          return true;
      }
      call_user_func_array (cb, parameters)
      {
         let func = null;
          if (typeof cb === 'string') {
              func = (typeof this[cb] === 'function') ? this[cb] : func = (newFunction(null, 'return ' + cb))();
          } else if (cb instanceof Array) {
              func = (typeof cb[0] == 'string') ? eval(cb[0] + "['" + cb[1] + "']") : func = cb[0][cb[1]];
          } else if (typeof cb === 'function') {
              func = cb;
          }
          if (typeof func != 'function') {
              throw new Error(func + ' is not a valid function');
          }
          if (typeof parameters == 'undefined') {
              var tmp_ary = [];
              var parameters = Array.prototype.slice.call(tmp_ary, 1);
          }
          return (typeof cb[0] === 'string') ? func.apply(eval(cb[0]), parameters) : (typeof cb[0] !== 'object') ? func.apply(null, parameters) : func.apply(cb[0], parameters);
      }
}





/*

function start(param =null){
    console.log('start hook' + param)
}
function end(param=nll){
    console.log('end hook' + param)
}
Hook.instance().addAction('RUN',start('this is a param'));
Hook.instance().addAction('RUN',end('this is a parm sidf d'));
console.log('RUN')
Hook.instance().doAction('RUN');
*
*/
